package com.jzo2o.customer.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.api.publics.SmsCodeApi;
import com.jzo2o.api.publics.dto.response.BooleanResDTO;
import com.jzo2o.common.enums.SmsBussinessTypeEnum;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.customer.constants.ServerConstance;
import com.jzo2o.customer.mapper.RegistMapper;
import com.jzo2o.customer.model.domain.InstitutionStaff;
import com.jzo2o.customer.model.domain.ServeProvider;
import com.jzo2o.customer.model.dto.request.RegistryReqDto;
import com.jzo2o.customer.service.IRegistService;
import com.jzo2o.customer.service.IServeProviderService;
import com.jzo2o.customer.util.EncodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class RegistServiceImpl extends ServiceImpl<RegistMapper, InstitutionStaff> implements IRegistService {
@Autowired
private SmsCodeApi smsCodeApi;
 private static final EncodeUtil encodeUtil = new EncodeUtil();
@Autowired
private IServeProviderService serveProviderService;
@Autowired
private RedisTemplate redisTemplate;
@Resource
private PasswordEncoder bCryptPasswordEncoder;

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public void registUser(RegistryReqDto registryReqDto) {
        String verifyCode = registryReqDto.getVerifyCode();
        //手机号没有注册过且已发送验证码 设置一个验证码自动过期的缓存
        redisTemplate.opsForValue().set(encodeUtil.REGISTRY_CODE+verifyCode, TimeUnit.MINUTES);

        String phone = registryReqDto.getPhone();
        String password = registryReqDto.getPassword();
        //判断手机号和验证码是否为合法长度/ 以及判空
        if (phone.length()!=11 && verifyCode.length()!=6&& StringUtils.isBlank(password)&&StringUtils.isBlank(phone)){
            throw new ForbiddenOperationException("您输入的参数不合法");
        }
        //查询该手机号在数据库中是否已经注册过
        ServeProvider serveProvider = serveProviderService.lambdaQuery().eq(ServeProvider::getPhone, phone).one();
        if (ObjectUtil.isNotEmpty(serveProvider)){
            throw new ForbiddenOperationException("该手机号已注册");
        }
        //校验密码是否符合规则
        boolean validPassword = encodeUtil.isValidPassword(password);
        if (!validPassword){
            throw new ForbiddenOperationException("密码不合法");
        }
        //远程调用smsApi校验验证码
        BooleanResDTO verify = smsCodeApi.verify(phone, SmsBussinessTypeEnum.INSTITION_REGISTER, verifyCode);
        if(verify.getIsSuccess()){
            if (redisTemplate.opsForValue().get(encodeUtil.REGISTRY_CODE+verifyCode)!=null){
                serveProviderService.add(phone, ServerConstance.TYPE_INSTITUTION, password);
            }
            log.info("注册成功");
        }else{
            throw new ForbiddenOperationException("验证码不正确");
        }

    }

}
